
#pragma once

#include <exception>
#include <string>

namespace ct
{

    class exception : std::exception
    {
    public:
        std::string msg;

        exception(const std::string &m) : msg(m)
        {
        }
    };

    class c_test
    {
    public:
        std::string name;
        c_test(const std::string &_name) : name(_name)
        {
        }
        virtual void main() {}
        static void add(c_test *ptr);
    };

    template <class C>
    class c_test_cdt
    {
    public:
        c_test_cdt(const std::string &name)
        {
            auto *ptr = new C();
            c_test::add(ptr);
        }
    };

#define CTEST_BEGIN(name)                           \
    namespace                                       \
    {                                               \
        class childc_test##name : public ct::c_test \
        {                                           \
        private:                                    \
        public:                                     \
            childc_test##name(const std::string &name) : c_test(name) {}

#define CTEST_END(name) \
    }                   \
    g_test_obj##name;   \
    }

    void c_test_run_all(void);

#define CT_ASSERT(cond) \
    if (!(cond))        \
    {                   \
        throw exception( )                   \
    }
}